//*********************************************************
//
//    Copyright (c) Microsoft. All rights reserved.
//    This code is licensed under the Apache License, Version 2.0.
//    THIS CODE IS PROVIDED *AS IS* WITHOUT WARRANTY OF
//    ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING ANY
//    IMPLIED WARRANTIES OF FITNESS FOR A PARTICULAR
//    PURPOSE, MERCHANTABILITY, OR NON-INFRINGEMENT.
//
//*********************************************************

namespace Microsoft.Research.ScientificWorkflow.UIDesigner
{
    #region Using Directives
    using System;
    using System.Windows;
    using System.Windows.Controls;
    using System.Windows.Media;
    using System.Windows.Shapes;
    using Microsoft.Research.ScientificWorkflow.TridentModel;
    using Microsoft.Research.ScientificWorkflow.TridentUtilities;
    #endregion

    /// <summary>
    /// This Class is used to represent the START
    /// UI Element while rendering the workflows.
    /// </summary>
    public class StartElement : DockPanel, ITridentUIElement
    {
        #region Privtae Variables

        /// <summary>
        /// This is used to specify the Color of the border.
        /// </summary>
        private static Brush borderBrush = new SolidColorBrush(Colors.Transparent);

        /// <summary>
        /// This is used to specify the Color of the Connectivity Element.
        /// </summary>
        private static Brush flowBorderBrush = new SolidColorBrush(Colors.DarkCyan);

        /// <summary>
        /// This is used to specify the background Color of the UI Element as a whole.
        /// </summary>
        private static Brush flowFillBrush = new SolidColorBrush(Colors.Transparent);

        /// <summary>
        /// Thickness of the border.
        /// </summary>
        private static double flowShapeThickness = 1.5;

        /// <summary>
        /// Height of the Connectivity Element.
        /// </summary>
        private double flowShapeHeight = 10.0;

        /// <summary>
        /// Width of the Connectivity Element.
        /// </summary>
        private double flowShapeWidth = 10.0;

        /// <summary>
        /// Margin of the Connectivity Element.
        /// </summary>
        private static double flowShapeVertMargin = 1.0;

        /// <summary>
        /// Connectivity Element.
        /// </summary>
        private FrameworkElement rightFlowConnection;

        private bool isImageRequired = true;

        #endregion

        /// <summary>
        /// This is the Conctructor for this class.
        /// This is used to Initialize teh Ui Element.
        /// </summary>
        public StartElement(bool isImageRequired)
            : base()
        {
            this.isImageRequired = isImageRequired;
            if (!this.isImageRequired)
            {
                this.flowShapeHeight = 2;
                this.flowShapeWidth = 2;
            }

            this.InitComponent();

            this.UpdateClick += delegate(object sender, ModelEventArgs args) { };
            this.SelectElement += new EventHandler(StartElement_SelectElement);
            this.DeleteElement += new EventHandler(StartElement_DeleteElement);
            this.ShowProperties += new EventHandler(this.OnShowProperties);
            this.InsertIntoSubsection += new EventHandler(StartElement_InsertIntoSubsection);
            this.ProvenanceMenuClick += new EventHandler<ProvenanceModeEventArgs>(EndElement_ProvenanceMenuClick);
        }

        /// <summary>
        /// This is used to create an Ui Element for the START of the WorkFlow.
        /// </summary>
        private void InitComponent()
        {
            Border headerBorder = null;            
            Height = 25;
            Width = 25;

            // Set the background of the UI Element.
            Background = new SolidColorBrush(Colors.Transparent);

            // This Creates the Body of the Element.
            // i.e. the Connectivity UI Element and the Image .
            UIElement header = this.InitHeader();

            // Sets the Properties of the Header Border
            headerBorder = new Border();
            headerBorder.BorderBrush = borderBrush;
            headerBorder.BorderThickness = new Thickness(0, 0, 0, 1);
            headerBorder.Child = header;

            // Adds the Header to the Ui Element
            Children.Add(headerBorder);

            // Docks the Header to the TOP of the Dockpanel.
            DockPanel.SetDock(headerBorder, Dock.Top);
        }

        /// <summary>
        /// Initializes the body of the Ui Element in the format
        /// the Image and the Connectivity Element.
        /// </summary>
        /// <returns>The UI element created.</returns>
        private UIElement InitHeader()
        {
            Grid headerPanel = null;
            ColumnDefinition flowOutColumn = null;
            ColumnDefinition headerColumn = null;

            Canvas flowOutCanvas = null;
            Image headerImage = null;
            Rectangle flowOutRect = null;

            headerPanel = new Grid();

            // Sets the propeties of the Connectivity UI Element.
            flowOutColumn = new ColumnDefinition();
            flowOutColumn.Width = new GridLength(flowShapeWidth / 2.0);

            // Sets the propeties of the Image UI Element.
            headerColumn = new ColumnDefinition();
            headerColumn.Width = new GridLength(1, GridUnitType.Star);

            #region Set the Value for the Connectivity UI Element
            // Adds the Connectivity UI Element to the Body
            headerPanel.ColumnDefinitions.Add(headerColumn);
            headerPanel.ColumnDefinitions.Add(flowOutColumn);

            // Sets the propeties of the Connectivity UI Element.
            flowOutCanvas = new Canvas();
            flowOutCanvas.Height = flowShapeWidth;
            flowOutCanvas.VerticalAlignment = VerticalAlignment.Center;

            flowOutRect = new Rectangle();
            flowOutRect.Width = flowShapeWidth;
            flowOutRect.Height = flowShapeHeight;
            flowOutRect.Stroke = flowBorderBrush;
            flowOutRect.Fill = flowFillBrush;
            flowOutRect.StrokeThickness = flowShapeThickness;
            flowOutRect.Stroke = new SolidColorBrush((Color)ColorConverter.ConvertFromString("#FF94B3C4"));
            this.rightFlowConnection = flowOutRect;

            #endregion

            #region Set the Value for the Image UI Element

            headerImage = new Image();
            ImageSourceConverter converter = new ImageSourceConverter();
            headerImage.Source = (ImageSource)converter.ConvertFromString(@"pack://Application:,,,/Microsoft.Research.ScientificWorkflow.TridentUtilities;component/Images/ScientificWorkflow/WFStart.PNG");
            
            headerPanel.HorizontalAlignment = HorizontalAlignment.Stretch;
            headerPanel.VerticalAlignment = VerticalAlignment.Stretch;
            headerPanel.Margin = new Thickness(0, 0, 0, 2);
            #endregion

            // Sets the Padding.
            Canvas.SetTop(flowOutRect, flowShapeVertMargin);
            Canvas.SetRight(flowOutRect, -(flowShapeWidth / 2.0));

            Grid.SetColumn(flowOutCanvas, 1);
            Grid.SetColumn(headerImage, 0);

            flowOutCanvas.Children.Add(flowOutRect);

            if (isImageRequired)
            {
                // Adds the START Image element to the Main Grid
                headerPanel.Children.Add(headerImage);
            }

            // Adds the Connectivty element to the Main Grid
            headerPanel.Children.Add(flowOutCanvas);
            return headerPanel;
        }

        #region ITridentUIElement Members

        public void ApplySelectedStyle()
        {
            throw new NotImplementedException();
        }

        public void ApplyUnselectedStyle()
        {
            throw new NotImplementedException();
        }

        public void CreateContextMenu()
        {
            throw new NotImplementedException();
        }

        public event EventHandler DeleteElement;

        public Point GetBindingEndpoint(UIElement relativeTo)
        {
            throw new NotImplementedException();
        }

        public Point GetBindingStartPoint(UIElement relativeTo)
        {
            throw new NotImplementedException();
        }

        public int FetchUIElementPosition()
        {
            return -1;
        }

        public BaseModel Model
        {
            get { return null; }
        }

        public event EventHandler SelectElement;

        public event EventHandler ShowProperties;

        public event EventHandler InsertIntoSubsection;

        public event EventHandler<ProvenanceModeEventArgs> ProvenanceMenuClick;

        public event EventHandler<ModelEventArgs> UpdateClick;

        public FrameworkElement LeftControlFlowConnectionElement
        {
            get { return this.rightFlowConnection; }
        }

        public FrameworkElement RightControlFlowConnectionElement
        {
            get { return this.rightFlowConnection; }
        }

        #endregion

        private void StartElement_DeleteElement(object sender, EventArgs e)
        {
            // Note: Null implementation to avoid warning
        }

        private void StartElement_SelectElement(object sender, EventArgs e)
        {
            // Note: Null implementation to avoid warning
        }

        private void OnShowProperties(object sender, EventArgs e)
        {

        }

        private void StartElement_InsertIntoSubsection(object sender, EventArgs e)
        {

        }

        private void EndElement_ProvenanceMenuClick(object sender, ProvenanceModeEventArgs e)
        {
            // Note: Null implementation to avoid warning
        }
    }
}

